/**
 * @file Layer
 */
var pathToRegexp = require('path-to-regexp');

var hasOwnProperty = Object.prototype.hasOwnProperty;

function Layer(path, options, fn) {
    if (! (this instanceof Layer)) {
        return new Layer(path, options, fn);
    }

    var opts = options || {};

    this.handle = fn;
    this.name = fn.name || '<anonymous>';
    this.path = undefined;
    this.params = undefined;
    this.regexp = pathToRegexp(path, this.keys = [], opts);

    if (path === '/' && opts.end === false) {
        this.regexp.fast_slash = true;
    }
}


Layer.prototype.handleError = function (error, req, res, next) {
    var fn = this.handle;

    try {
        fn(error, req, res, next);
    } catch (err) {
        next(err);
    }
};

Layer.prototype.handleRequest = function (req, res, next) {
    var handle = this.handle;

    try {
      handle(req, res, next);
    }
    catch (err) {
        next(err);
    }
};


Layer.prototype.match = function (path) {
    if (path == null) {
        this.params = undefined;
        this.path = undefined;
        return false;
    }

    if (this.regexp.fast_slash) {
        this.params = {};
        this.path = '';
        return true;
    }
    

    var match = this.regexp.exec(path);

    if (!match) {
        this.params = undefined;
        this.path = undefined;
        return false;
    }

    this.params = {};
    this.path = match[0];

    var keys = this.keys;
    var params = this.params;

    for (var i = 1; i < match.length; i++) {
        var key = keys[i - 1];
        var prop = key.name;
        var val = match[i];

        if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
            params[prop] = val;
        }
    }

    return true;
};


module.exports = Layer;
